package com.lianjia.analysis.service.impl;

import com.github.abel533.echarts.Option;
import com.github.abel533.echarts.axis.CategoryAxis;
import com.github.abel533.echarts.axis.ValueAxis;
import com.github.abel533.echarts.code.Orient;
import com.github.abel533.echarts.code.SeriesType;
import com.github.abel533.echarts.code.Trigger;
import com.github.abel533.echarts.data.Data;
import com.github.abel533.echarts.series.Bar;
import com.github.abel533.echarts.series.Line;
import com.github.abel533.echarts.series.Scatter;
import com.lianjia.analysis.model.HouseInfo;
import com.lianjia.analysis.repository.HouseInfoRepository;
import com.lianjia.analysis.service.HousePriceAnalysisService;
import com.lianjia.analysis.service.cache.RedisCacheService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 房价分析服务实现类
 */
@Service
public class HousePriceAnalysisServiceImpl implements HousePriceAnalysisService {

    private static final Logger logger = LoggerFactory.getLogger(HousePriceAnalysisServiceImpl.class);
    
    private static final String CACHE_KEY_CITIES = "analysis:cities";
    private static final String CACHE_KEY_CITY_HOUSE_COUNT = "analysis:city:house:count";
    private static final String CACHE_KEY_CITY_AVG_PRICE = "analysis:city:avg:price";
    private static final String CACHE_KEY_CITY_MEDIAN_PRICE = "analysis:city:median:price";
    private static final String CACHE_KEY_CITY_PRICE_DIST = "analysis:city:price:dist";
    private static final String CACHE_KEY_CITY_AREA_DIST = "analysis:city:area:dist";
    private static final String CACHE_KEY_CITY_LAYOUT_DIST = "analysis:city:layout:dist";
    private static final String CACHE_KEY_CITY_ORIENTATION_DIST = "analysis:city:orientation:dist";
    private static final String CACHE_KEY_CITY_DECORATION_DIST = "analysis:city:decoration:dist";
    private static final String CACHE_KEY_CITY_FLOOR_DIST = "analysis:city:floor:dist";
    private static final String CACHE_KEY_CITY_PRICE_AREA = "analysis:city:%s:price:area";
    private static final String CACHE_KEY_CITY_DISTRICT_PRICE = "analysis:city:%s:district:price";
    private static final String CACHE_KEY_CITY_PRICE_TREND = "analysis:city:%s:price:trend";

    @Autowired
    private HouseInfoRepository houseInfoRepository;

    @Autowired
    private MongoTemplate mongoTemplate;
    
    @Autowired
    private RedisCacheService redisCacheService;

    @Override
    public List<String> getAllCities() {
        // 先从缓存中获取
        List<String> cities = redisCacheService.getList(CACHE_KEY_CITIES);
        
        if (cities == null || cities.isEmpty()) {


            logger.debug("Cities not found in cache, querying from database");

            if (cities == null) {
                        cities = houseInfoRepository.findDistinctCities();
    
                          // 存入缓存，设置24小时过期
                            if (!cities.isEmpty()) {
                                redisCacheService.setList(CACHE_KEY_CITIES, cities);
                                redisCacheService.expire(CACHE_KEY_CITIES, 24, TimeUnit.HOURS);
                                logger.debug("Cities cached successfully: {}", cities);
                            }
                        logger.debug("Cities cached successfully: {}", cities);
                    }

            // 使用MongoDB聚合查询获取所有不同的城市名称
           
        } else {
            logger.debug("Cities found in cache: {}", cities);
        }
        
        return cities;
    }

    @Override
    public Map<String, Integer> getCityHouseCount() {
        // 先从缓存中获取
        Map<String, Integer> result = redisCacheService.getMap(CACHE_KEY_CITY_HOUSE_COUNT);
        
        if (result == null || result.isEmpty()) {
            logger.debug("City house count not found in cache, querying from database");
            result = new HashMap<>();
            List<String> cities = getAllCities();
            
            for (String city : cities) {
                int count = houseInfoRepository.findByCityName(city).size();
                result.put(city, count);
            }
            
            // 存入缓存，设置6小时过期
            if (!result.isEmpty()) {
                redisCacheService.setMap(CACHE_KEY_CITY_HOUSE_COUNT, result);
                redisCacheService.expire(CACHE_KEY_CITY_HOUSE_COUNT, 6, TimeUnit.HOURS);
                logger.debug("City house count cached successfully");
            }
        } else {
            logger.debug("City house count found in cache");
        }
        
        return result;
    }

    @Override
    public Map<String, Double> getCityAveragePrice() {
        // 先从缓存中获取
        Map<String, Double> result = redisCacheService.getMap(CACHE_KEY_CITY_AVG_PRICE);
        
        if (result == null || result.isEmpty()) {
            logger.debug("City average price not found in cache, querying from database");
            result = new HashMap<>();
            List<String> cities = getAllCities();
            
            for (String city : cities) {
                List<HouseInfo> houses = houseInfoRepository.findPriceStatsByCityName(city);
                double totalPrice = 0;
                int count = 0;
                
                for (HouseInfo house : houses) {
                    if (house.getPrice() != null && house.getPrice().getTotalPrice() != null) {
                        totalPrice += house.getPrice().getTotalPrice();
                        count++;
                    }
                }
                
                double avgPrice = count > 0 ? totalPrice / count : 0;
                result.put(city, avgPrice);
            }
            
            // 存入缓存，设置6小时过期
            if (!result.isEmpty()) {
                redisCacheService.setMap(CACHE_KEY_CITY_AVG_PRICE, result);
                redisCacheService.expire(CACHE_KEY_CITY_AVG_PRICE, 6, TimeUnit.HOURS);
                logger.debug("City average price cached successfully");
            }
        } else {
            logger.debug("City average price found in cache");
        }
        
        return result;
    }

    @Override
    public Map<String, Double> getCityMedianPrice() {
        // 先从缓存中获取
        Map<String, Double> result = redisCacheService.getMap(CACHE_KEY_CITY_MEDIAN_PRICE);
        
        if (result == null || result.isEmpty()) {
            logger.debug("City median price not found in cache, querying from database");
            result = new HashMap<>();
            List<String> cities = getAllCities();
            
            for (String city : cities) {
                List<HouseInfo> houses = houseInfoRepository.findPriceStatsByCityName(city);
                List<Double> prices = new ArrayList<>();
                
                for (HouseInfo house : houses) {
                    if (house.getPrice() != null && house.getPrice().getTotalPrice() != null) {
                        prices.add(house.getPrice().getTotalPrice());
                    }
                }
                
                Collections.sort(prices);
                double median = 0;
                if (!prices.isEmpty()) {
                    if (prices.size() % 2 == 0) {
                        median = (prices.get(prices.size() / 2 - 1) + prices.get(prices.size() / 2)) / 2;
                    } else {
                        median = prices.get(prices.size() / 2);
                    }
                }
                
                result.put(city, median);
            }
            
            // 存入缓存，设置6小时过期
            if (!result.isEmpty()) {
                redisCacheService.setMap(CACHE_KEY_CITY_MEDIAN_PRICE, result);
                redisCacheService.expire(CACHE_KEY_CITY_MEDIAN_PRICE, 6, TimeUnit.HOURS);
                logger.debug("City median price cached successfully");
            }
        } else {
            logger.debug("City median price found in cache");
        }
        
        return result;
    }

    @Override
    public Map<String, Map<String, Integer>> getCityPriceDistribution() {
        // 先从缓存中获取
        Map<String, Map<String, Integer>> result = redisCacheService.getMap(CACHE_KEY_CITY_PRICE_DIST);
        
        if (result == null || result.isEmpty()) {
            logger.debug("City price distribution not found in cache, querying from database");
            result = new HashMap<>();
            List<String> cities = getAllCities();
            
            for (String city : cities) {
                List<HouseInfo> houses = houseInfoRepository.findPriceStatsByCityName(city);
                Map<String, Integer> distribution = new HashMap<>();
                
                // 定义价格区间
                distribution.put("0-50万", 0);
                distribution.put("50-100万", 0);
                distribution.put("100-150万", 0);
                distribution.put("150-200万", 0);
                distribution.put("200-300万", 0);
                distribution.put("300-500万", 0);
                distribution.put("500万以上", 0);
                
                for (HouseInfo house : houses) {
                    if (house.getPrice() != null && house.getPrice().getTotalPrice() != null) {
                        double price = house.getPrice().getTotalPrice();
                        
                        if (price <= 50) {
                            distribution.put("0-50万", distribution.get("0-50万") + 1);
                        } else if (price <= 100) {
                            distribution.put("50-100万", distribution.get("50-100万") + 1);
                        } else if (price <= 150) {
                            distribution.put("100-150万", distribution.get("100-150万") + 1);
                        } else if (price <= 200) {
                            distribution.put("150-200万", distribution.get("150-200万") + 1);
                        } else if (price <= 300) {
                            distribution.put("200-300万", distribution.get("200-300万") + 1);
                        } else if (price <= 500) {
                            distribution.put("300-500万", distribution.get("300-500万") + 1);
                        } else {
                            distribution.put("500万以上", distribution.get("500万以上") + 1);
                        }
                    }
                }
                
                result.put(city, distribution);
            }
            
            // 存入缓存，设置6小时过期
            if (!result.isEmpty()) {
                redisCacheService.setMap(CACHE_KEY_CITY_PRICE_DIST, result);
                redisCacheService.expire(CACHE_KEY_CITY_PRICE_DIST, 6, TimeUnit.HOURS);
                logger.debug("City price distribution cached successfully");
            }
        } else {
            logger.debug("City price distribution found in cache");
        }
        
        return result;
    }

    @Override
    public Map<String, Map<String, Integer>> getCityAreaDistribution() {
        Map<String, Map<String, Integer>> result = new HashMap<>();
        List<String> cities = getAllCities();
        
        for (String city : cities) {
            List<HouseInfo> houses = houseInfoRepository.findByCityName(city);
            Map<String, Integer> distribution = new HashMap<>();
            
            // 定义面积区间
            distribution.put("50㎡以下", 0);
            distribution.put("50-70㎡", 0);
            distribution.put("70-90㎡", 0);
            distribution.put("90-110㎡", 0);
            distribution.put("110-130㎡", 0);
            distribution.put("130-150㎡", 0);
            distribution.put("150㎡以上", 0);
            
            for (HouseInfo house : houses) {
                Double area = house.getAreaValue();
                if (area != null) {
                    if (area < 50) {
                        distribution.put("50㎡以下", distribution.get("50㎡以下") + 1);
                    } else if (area < 70) {
                        distribution.put("50-70㎡", distribution.get("50-70㎡") + 1);
                    } else if (area < 90) {
                        distribution.put("70-90㎡", distribution.get("70-90㎡") + 1);
                    } else if (area < 110) {
                        distribution.put("90-110㎡", distribution.get("90-110㎡") + 1);
                    } else if (area < 130) {
                        distribution.put("110-130㎡", distribution.get("110-130㎡") + 1);
                    } else if (area < 150) {
                        distribution.put("130-150㎡", distribution.get("130-150㎡") + 1);
                    } else {
                        distribution.put("150㎡以上", distribution.get("150㎡以上") + 1);
                    }
                }
            }
            
            result.put(city, distribution);
        }
        
        return result;
    }

    @Override
    public Map<String, Map<String, Integer>> getCityLayoutDistribution() {
        Map<String, Map<String, Integer>> result = new HashMap<>();
        List<String> cities = getAllCities();
        
        for (String city : cities) {
            List<HouseInfo> houses = houseInfoRepository.findByCityName(city);
            Map<String, Integer> distribution = new HashMap<>();
            
            for (HouseInfo house : houses) {
                if (house.getDetails() != null && house.getDetails().containsKey("configuration")) {
                    String layout = house.getDetails().get("configuration");
                    distribution.put(layout, distribution.getOrDefault(layout, 0) + 1);
                }
            }
            
            result.put(city, distribution);
        }
        
        return result;
    }

    @Override
    public Map<String, Map<String, Integer>> getCityOrientationDistribution() {
        Map<String, Map<String, Integer>> result = new HashMap<>();
        List<String> cities = getAllCities();
        
        for (String city : cities) {
            List<HouseInfo> houses = houseInfoRepository.findByCityName(city);
            Map<String, Integer> distribution = new HashMap<>();
            
            for (HouseInfo house : houses) {
                if (house.getDetails() != null && house.getDetails().containsKey("towards")) {
                    String orientation = house.getDetails().get("towards");
                    distribution.put(orientation, distribution.getOrDefault(orientation, 0) + 1);
                }
            }
            
            result.put(city, distribution);
        }
        
        return result;
    }

    @Override
    public Map<String, Map<String, Integer>> getCityDecorationDistribution() {
        Map<String, Map<String, Integer>> result = new HashMap<>();
        List<String> cities = getAllCities();
        
        for (String city : cities) {
            List<HouseInfo> houses = houseInfoRepository.findByCityName(city);
            Map<String, Integer> distribution = new HashMap<>();
            
            for (HouseInfo house : houses) {
                if (house.getDetails() != null && house.getDetails().containsKey("decorate")) {
                    String decoration = house.getDetails().get("decorate");
                    distribution.put(decoration, distribution.getOrDefault(decoration, 0) + 1);
                }
            }
            
            result.put(city, distribution);
        }
        
        return result;
    }

    @Override
    public Map<String, Map<String, Integer>> getCityFloorDistribution() {
        Map<String, Map<String, Integer>> result = new HashMap<>();
        List<String> cities = getAllCities();
        
        for (String city : cities) {
            List<HouseInfo> houses = houseInfoRepository.findByCityName(city);
            Map<String, Integer> distribution = new HashMap<>();
            
            for (HouseInfo house : houses) {
                if (house.getDetails() != null && house.getDetails().containsKey("storey")) {
                    String floor = house.getDetails().get("storey");
                    if (floor.contains("低")) {
                        distribution.put("低楼层", distribution.getOrDefault("低楼层", 0) + 1);
                    } else if (floor.contains("中")) {
                        distribution.put("中楼层", distribution.getOrDefault("中楼层", 0) + 1);
                    } else if (floor.contains("高")) {
                        distribution.put("高楼层", distribution.getOrDefault("高楼层", 0) + 1);
                    } else {
                        distribution.put("其他", distribution.getOrDefault("其他", 0) + 1);
                    }
                }
            }
            
            result.put(city, distribution);
        }
        
        return result;
    }

    @Override
    public Option getPriceAreaScatterData(String cityName) {
        // 先从缓存中获取
        String cacheKey = String.format(CACHE_KEY_CITY_PRICE_AREA, cityName);
        Option option = null;
        try {
            option = (Option) redisCacheService.get(cacheKey);
        } catch (ClassCastException e) {
            // 如果出现类型转换异常，删除缓存重新生成
            logger.warn("ClassCastException when getting price area data for {}: {}", cityName, e.getMessage());
            redisCacheService.delete(cacheKey);
            option = null;
        }
        
        if (option == null) {
            logger.debug("Price area scatter data for city {} not found in cache, querying from database", cityName);
            option = new Option();
            option.title().text(cityName + "房价与面积散点图").left("center");
            option.tooltip().trigger(Trigger.item).formatter("{a} <br/>{b} : {c}");
            option.xAxis(new ValueAxis().name("面积(㎡)"));
            option.yAxis(new ValueAxis().name("总价(万元)"));
            option.legend().data("房源").left("left");
            
            List<HouseInfo> houses = houseInfoRepository.findByCityName(cityName);
            List<Object[]> data = new ArrayList<>();
            
            for (HouseInfo house : houses) {
                if (house.getAreaValue() != null && house.getPrice() != null && house.getPrice().getTotalPrice() != null) {
                    data.add(new Object[]{house.getAreaValue(), house.getPrice().getTotalPrice()});
                }
            }
            
            option.series(new Scatter("房源").data(data.toArray()));
            
            try {
                // 存入缓存，设置6小时过期
                redisCacheService.set(cacheKey, option, 6, TimeUnit.HOURS);
                logger.debug("Price area scatter data for city {} cached successfully", cityName);
            } catch (Exception e) {
                logger.error("Error caching price area data for {}: {}", cityName, e.getMessage());
                // 出现异常时不使用缓存，直接返回当前生成的数据
            }
        } else {
            logger.debug("Price area scatter data for city {} found in cache", cityName);
        }
        
        return option;
    }

    @Override
    public Option getCityDistrictPriceRanking(String cityName) {
        // 先从缓存中获取
        String cacheKey = String.format(CACHE_KEY_CITY_DISTRICT_PRICE, cityName);
        Option option = (Option) redisCacheService.get(cacheKey);
        
        if (option == null) {
            logger.debug("District price ranking for city {} not found in cache, querying from database", cityName);
            option = new Option();
            option.title().text(cityName + "各区域房价排行").left("center");
            option.tooltip().trigger(Trigger.axis);
            option.legend().data("均价(万元/㎡)").left("left");
            
            // 获取城市下所有区域的均价
            Map<String, Double> districtAvgPrices = new HashMap<>();
            List<HouseInfo> houses = houseInfoRepository.findByCityName(cityName);
            
            // 按区域分组计算均价
            Map<String, List<HouseInfo>> districtHouses = houses.stream()
                    .filter(h -> h.getDistrict() != null && !h.getDistrict().isEmpty())
                    .collect(Collectors.groupingBy(HouseInfo::getDistrict));
            
            for (Map.Entry<String, List<HouseInfo>> entry : districtHouses.entrySet()) {
                String district = entry.getKey();
                List<HouseInfo> districtHouseList = entry.getValue();
                
                double totalUnitPrice = 0;
                int count = 0;
                
                for (HouseInfo house : districtHouseList) {
                    if (house.getPrice() != null && house.getPrice().getUnitPrice() != null) {
                        totalUnitPrice += house.getPrice().getUnitPrice();
                        count++;
                    }
                }
                
                double avgUnitPrice = count > 0 ? totalUnitPrice / count : 0;
                districtAvgPrices.put(district, avgUnitPrice);
            }
            
            // 按均价排序
            List<Map.Entry<String, Double>> sortedDistricts = new ArrayList<>(districtAvgPrices.entrySet());
            sortedDistricts.sort(Map.Entry.comparingByValue(Comparator.reverseOrder()));
            
            // 取前10个区域
            List<Map.Entry<String, Double>> top10Districts = sortedDistricts.size() > 10 ? 
                    sortedDistricts.subList(0, 10) : sortedDistricts;
            
            // 构建图表数据
            List<String> districts = new ArrayList<>();
            List<Double> prices = new ArrayList<>();
            
            for (Map.Entry<String, Double> entry : top10Districts) {
                districts.add(entry.getKey());
                prices.add(entry.getValue());
            }
            
            CategoryAxis xAxis = new CategoryAxis();
            xAxis.data(districts.toArray());
            xAxis.axisLabel().rotate(45);
            option.xAxis(xAxis);
            
            option.yAxis(new ValueAxis().name("均价(万元/㎡)"));
            
            Bar bar = new Bar("均价(万元/㎡)");
            for (int i = 0; i < districts.size(); i++) {
                bar.data(prices.get(i));
            }
            
            option.series(bar);
            
            // 存入缓存，设置6小时过期
            redisCacheService.set(cacheKey, option, 6, TimeUnit.HOURS);
            logger.debug("District price ranking for city {} cached successfully", cityName);
        } else {
            logger.debug("District price ranking for city {} found in cache", cityName);
        }
        
        return option;
    }

    @Override
    public Option getCityPriceTrend(String cityName) {
        // 先从缓存中获取
        String cacheKey = String.format(CACHE_KEY_CITY_PRICE_TREND, cityName);
        Option option = (Option) redisCacheService.get(cacheKey);
        
        if (option == null) {
            logger.debug("Price trend for city {} not found in cache, generating data", cityName);
            option = new Option();
            option.title().text(cityName + "房价走势(近12个月)").left("center");
            option.tooltip().trigger(Trigger.axis);
            option.legend().data("均价(万元/㎡)").left("left");
            
            // 由于数据限制，模拟生成12个月的房价趋势数据
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -11); // 从11个月前开始
            
            List<String> months = new ArrayList<>();
            List<Double> prices = new ArrayList<>();
            
            // 获取当前城市的均价作为基准
            Map<String, Double> cityAvgPrices = getCityAveragePrice();
            double basePrice = cityAvgPrices.getOrDefault(cityName, 1.0) / 10; // 转换为万元/㎡
            if (basePrice <= 0) basePrice = 1.0;
            
            Random random = new Random();
            
            for (int i = 0; i < 12; i++) {
                // 生成月份标签
                int year = calendar.get(Calendar.YEAR);
                int month = calendar.get(Calendar.MONTH) + 1;
                String monthLabel = year + "-" + (month < 10 ? "0" + month : month);
                months.add(monthLabel);
                
                // 生成该月的房价数据（在基准价格上随机波动）
                double fluctuation = random.nextDouble() * 0.1 - 0.05; // -5%到+5%的波动
                double monthPrice = basePrice * (1 + fluctuation);
                prices.add(Math.round(monthPrice * 100) / 100.0); // 保留两位小数
                
                // 更新基准价格，模拟价格走势
                basePrice = monthPrice * (1 + (random.nextDouble() * 0.02 - 0.005)); // -0.5%到+1.5%的月增长率
                
                calendar.add(Calendar.MONTH, 1);
            }
            
            CategoryAxis xAxis = new CategoryAxis();
            xAxis.data(months.toArray());
            option.xAxis(xAxis);
            
            option.yAxis(new ValueAxis().name("均价(万元/㎡)"));
            
            Line line = new Line("均价(万元/㎡)");
            line.data(prices.toArray());
            option.series(line);
            
            // 存入缓存，设置24小时过期
            redisCacheService.set(cacheKey, option, 24, TimeUnit.HOURS);
            logger.debug("Price trend for city {} cached successfully", cityName);
        } else {
            logger.debug("Price trend for city {} found in cache", cityName);
        }
        
        return option;
    }

    @Override
    public List<HouseInfo> searchHouses(String cityName, Double minPrice, Double maxPrice, 
                                        Double minArea, Double maxArea, String layout, String location) {
        // 对于搜索功能，不使用缓存，每次都从数据库查询最新数据
        Query query = new Query();
        
        if (cityName != null && !cityName.isEmpty()) {
            query.addCriteria(Criteria.where("cityName").is(cityName));
        }
        
        if (location != null && !location.isEmpty()) {
            query.addCriteria(Criteria.where("district").is(location));
        }
        
        if (layout != null && !layout.isEmpty()) {
            query.addCriteria(Criteria.where("layout").is(layout));
        }
        
        if (minArea != null) {
            query.addCriteria(Criteria.where("areaValue").gte(minArea));
        }
        
        if (maxArea != null) {
            query.addCriteria(Criteria.where("areaValue").lte(maxArea));
        }
        
        if (minPrice != null) {
            query.addCriteria(Criteria.where("price.totalPrice").gte(minPrice));
        }
        
        if (maxPrice != null) {
            query.addCriteria(Criteria.where("price.totalPrice").lte(maxPrice));
        }
        
        return mongoTemplate.find(query, HouseInfo.class);
    }

    @Override
    public List<String> getDistrictsByCity(String cityName) {
        // 缓存键
        String cacheKey = "analysis:city:" + cityName + ":districts";
        
        // 先从缓存中获取
        List<String> districts = redisCacheService.getList(cacheKey);
        
        if (districts == null || districts.isEmpty()) {
            logger.debug("Districts for city {} not found in cache, querying from database", cityName);
            
            // 查询指定城市的所有区域
            Query query = new Query(Criteria.where("cityName").is(cityName));
            query.fields().include("district");
            List<HouseInfo> houseInfos = mongoTemplate.find(query, HouseInfo.class);
            
            districts = houseInfos.stream()
                    .map(HouseInfo::getDistrict)
                    .filter(district -> district != null && !district.isEmpty())
                    .distinct()
                    .sorted()
                    .collect(Collectors.toList());
            
            // 存入缓存，设置12小时过期
            if (!districts.isEmpty()) {
                redisCacheService.setList(cacheKey, districts);
                redisCacheService.expire(cacheKey, 12, TimeUnit.HOURS);
                logger.debug("Districts for city {} cached successfully: {}", cityName, districts);
            }
        } else {
            logger.debug("Districts for city {} found in cache: {}", cityName, districts);
        }
        
        return districts;
    }

    @Override
    public double getCityAverageArea(String cityName) {
        // 缓存键
        String cacheKey = "analysis:city:" + cityName + ":avg:area";
        
        // 先从缓存中获取
        Double avgArea = (Double) redisCacheService.get(cacheKey);
        
        if (avgArea == null) {
            logger.debug("Average area for city {} not found in cache, querying from database", cityName);
            
            // 查询指定城市的所有房源面积
            Query query = new Query(Criteria.where("cityName").is(cityName));
            query.fields().include("details.areaValue");
            List<HouseInfo> houseInfos = mongoTemplate.find(query, HouseInfo.class);
            
            // 计算平均面积
            double totalArea = 0;
            int count = 0;
            
            for (HouseInfo house : houseInfos) {
                Double area = house.getAreaValue();
                if (area != null) {
                    totalArea += area;
                    count++;
                }
            }
            
            avgArea = count > 0 ? totalArea / count : 0;
            
            // 存入缓存，设置12小时过期
            redisCacheService.set(cacheKey, avgArea, 12, TimeUnit.HOURS);
            logger.debug("Average area for city {} cached successfully: {}", cityName, avgArea);
        } else {
            logger.debug("Average area for city {} found in cache: {}", cityName, avgArea);
        }
        
        return avgArea;
    }
    
    @Override
    public Map<String, Integer> getDistrictHouseCounts(String cityName) {
        // 缓存键
        String cacheKey = "analysis:city:" + cityName + ":district:counts";
        
        // 先从缓存中获取
        Map<String, Integer> districtCounts = redisCacheService.getMap(cacheKey);
        
        if (districtCounts == null || districtCounts.isEmpty()) {
            logger.debug("District house counts for city {} not found in cache, querying from database", cityName);
            
            // 查询指定城市的所有房源
            Query query = new Query(Criteria.where("cityName").is(cityName));
            query.fields().include("district");
            List<HouseInfo> houseInfos = mongoTemplate.find(query, HouseInfo.class);
            
            // 按区域统计房源数量
            districtCounts = new HashMap<>();
            
            for (HouseInfo house : houseInfos) {
                String district = house.getDistrict();
                if (district != null && !district.isEmpty()) {
                    districtCounts.put(district, districtCounts.getOrDefault(district, 0) + 1);
                }
            }
            
            // 存入缓存，设置6小时过期
            if (!districtCounts.isEmpty()) {
                redisCacheService.setMap(cacheKey, districtCounts);
                redisCacheService.expire(cacheKey, 6, TimeUnit.HOURS);
                logger.debug("District house counts for city {} cached successfully", cityName);
            }
        } else {
            logger.debug("District house counts for city {} found in cache", cityName);
        }
        
        return districtCounts;
    }
} 